package com.xjscrm.server.service.grouppull.impl;

import com.alibaba.fastjson.JSONObject;
import com.baomidou.mybatisplus.core.metadata.OrderItem;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.uzai.mobile.collect.api.dto.MicaTransDto;
import com.uzai.mobile.collect.api.dto.msg.MicaGroupMemberAddMsg;
import com.uzai.mobile.collect.api.dto.msg.MicaGroupMemberItemMsg;
import com.uzai.mobile.collect.api.enums.MicaMsgSource;
import com.uzai.trace.TraceGenerate;
import com.xjscrm.common.annotation.MerId;
import com.xjscrm.common.entity.*;
import com.xjscrm.common.utils.DateUtil;
import com.xjscrm.common.utils.Tools;
import com.xjscrm.common.vo.grouppull.GroupPullData;
import com.xjscrm.common.vo.grouppull.GroupPullMsgData;
import com.xjscrm.common.vo.operatorplandevice.OperatorPlanDeviceRule;
import com.xjscrm.server.biz.RatelimitService;
import com.xjscrm.server.biz.mq.producer.SendMsgProducer;
import com.xjscrm.server.common.util.DeviceTools;
import com.xjscrm.server.common.util.SleepTimeTools;
import com.xjscrm.server.dto.grouppullmarketing.GroupPullMarketingQuery;
import com.xjscrm.server.mapper.*;
import com.xjscrm.server.service.grouppull.GroupPullDataService;
import com.xjscrm.server.service.grouppull.GroupPullMarketingService;
import com.xjscrm.server.service.msg.MsgSendService;
import com.xjscrm.server.vo.device.Device;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.lang3.StringUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.redis.core.RedisTemplate;
import org.springframework.scheduling.annotation.Async;
import org.springframework.stereotype.Service;

import java.util.List;
import java.util.concurrent.TimeUnit;

/**
 * 拉群管理
 *
 * @author makejava
 * @since 2024-03-01 17:01:12
 */
@Slf4j
@Service
public class GroupPushMarketingServiceImpl implements GroupPullMarketingService {

    @Autowired
    private RedisTemplate redisTemplate;
    @Autowired
    private SendMsgProducer sendMsgProducer;
    @Autowired
    private WwDeviceMapper wwDeviceMapper;
    @Autowired
    private WwGroupMapper wwGroupMapper;
    @Autowired
    private WwGroupMemberMapper wwGroupMemberMapper;
    @Autowired
    private WwGroupTagsRelationMapper wwGroupTagsRelationMapper;
    @Autowired
    private WwCustomerTagsMapper wwCustomerTagsMapper;
    @Autowired
    private WwCustomerMapper wwCustomerMapper;
    @Autowired
    private MsgSendService msgSendService;
    @Autowired
    private GroupPullMarketingMapper groupPullMarketingMapper;
    @Autowired
    private RatelimitService ratelimitService;
    @Autowired
    private GroupPullDataService groupPullDataService;
    @Autowired
    private WwCustomerBlacklistMapper wwCustomerBlacklistMapper;
    @Autowired
    private GroupPullConfigDeviceMapper groupPullConfigDeviceMapper;
    @Autowired
    private GroupPullJobDeviceMapper groupPullJobDeviceMapper;
    @Autowired
    private OperatePlanDeviceMapper operatePlanDeviceMapper;
    @Autowired
    private FaqReplyDeviceMapper faqReplyDeviceMapper;

    /**
     * 处理客户入群再次营销数据
     *
     * @param micaTransDto 客户入群参数
     * @return 实例对象
     */
    @Async("taskExecutorForEvent")
    @TraceGenerate //注入消息id标签
    public void joinGroupMarketingData(MicaTransDto micaTransDto) {

        try {
            log.info("--监控系统日志--开始--");
            if (StringUtils.isBlank(micaTransDto.getDeviceId())) {
                log.error("机器人wxid is null, merId={}", micaTransDto.getMerId());
                return;
            }

            //查询该机器人
            WwDevice wwDevice = wwDeviceMapper.queryByDeviceId(micaTransDto.getDeviceId(), micaTransDto.getMerId());
            if (wwDevice == null) {
                return;
            }
            Device device = DeviceTools.transDevice(wwDevice);
            if (device == null) {
                return;
            }

            //更新时间
            int now = DateUtil.getTime();

            MicaGroupMemberAddMsg micaGroupMemberAddMsg = JSONObject.parseObject(micaTransDto.getData().toString(), MicaGroupMemberAddMsg.class);
            if (micaGroupMemberAddMsg == null) {
                return;
            }

            //群微信id
            String groupId = micaGroupMemberAddMsg.getGroupId();
            //查询该群存不存在
            WwGroup wwGroup = wwGroupMapper.queryByDeviceUniqueIdAndGroupWxid(device.getDeviceUniqueId(), groupId);
            if (wwGroup == null) {
                return;
            }

            List<MicaGroupMemberItemMsg> members = micaGroupMemberAddMsg.getMembers();
            if (members == null || members.size() == 0) {
                return;
            }

            for (MicaGroupMemberItemMsg member : members) {
                try {
                    String wxid = member.getWxid();
                    //查询该成员对于的营销数据
                    List<GroupPullMarketing> groupPullMarketingList = groupPullMarketingMapper.findByDeviceUniqueIdAndWxid(device.getDeviceUniqueId(), wxid, groupId);
                    if (groupPullMarketingList != null && groupPullMarketingList.size() > 0) {
                        for (GroupPullMarketing groupPullMarketing : groupPullMarketingList) {
                            //模式(0-不进群营销；1-进群营销)
                            Integer model = Tools.getInteger(groupPullMarketing.getModel());
                            if (model.intValue() == 0) { //会员已经进群，将不进群营销全部关闭
                                groupPullMarketing.setStatus(0); //关闭
                                groupPullMarketing.setUpdateTime(now);
                                groupPullMarketingMapper.updateByIdSelective(groupPullMarketing);
                            } else if (model.intValue() == 1) {//会员已经进群，将进群营销全部开启
                                groupPullMarketing.setStatus(1); //开启
                                groupPullMarketing.setStartTime(now);
                                groupPullMarketing.setUpdateTime(now);
                                groupPullMarketingMapper.updateByIdSelective(groupPullMarketing);
                            }
                        }
                    }
                } catch (Exception e) {
                    log.error(e.getMessage(), e);
                }
            }
        }catch (Exception e) {
            log.error(e.getMessage(), e);
        }finally {
            log.info("--监控系统日志--结束--");
        }

    }

    /**
     * 自动处理拉群营销数据
     *
     * @param merId
     * @return null
     * @author jitwxs
     * @date 2024/3/8 17:12
     */
    @Async("taskExecutorForEvent")
    @TraceGenerate //注入消息id标签
    public void autoHanderMarketingData(@MerId Long merId) {

        try {
            log.info("--监控系统日志--开始--");

            //限流key
            String taskLimitKet = "-autoHanderMarketingData-taskLimitKey-merId=" + merId;
            Object object = redisTemplate.opsForValue().get(taskLimitKet);
            if (object != null) {
                return;
            }
            //保存限流key
            redisTemplate.opsForValue().set(taskLimitKet, taskLimitKet, 100, TimeUnit.SECONDS);

            log.info("-----处理拉群营销数据任务----merId=" + merId);

            try {
                //查询当前所有开启的自动发圈的配置方案
                int now = DateUtil.getTime();
                GroupPullMarketingQuery groupPullMarketingQuery = new GroupPullMarketingQuery();
                groupPullMarketingQuery.setMerId(merId);
                groupPullMarketingQuery.setStatus(1);                      //开启状态
                groupPullMarketingQuery.setHander(0);                      //没有执行过的
                groupPullMarketingQuery.setStartTimeEnd(now);              //查询所有已经开始营销数据

                //查询所有的自动发圈配置记录
                Page<GroupPullMarketing> page = new Page<>();
                page.setCurrent(1);//只查第一页
                page.setSize(10); //每页查询10个
                page.addOrder(OrderItem.asc("id"));//默认id升序
                Long idStart = 0L;
                List<GroupPullMarketing> groupPullMarketingList = groupPullMarketingMapper.findByList(page, groupPullMarketingQuery);
                while (groupPullMarketingList != null && groupPullMarketingList.size() > 0) {
                    for (GroupPullMarketing groupPullMarketing : groupPullMarketingList) {

                        if (groupPullMarketing.getId().longValue() >idStart.longValue()) {
                            idStart = groupPullMarketing.getId();
                        }

                        //限流判断
                        String rateLimitKey = "autoHanderMarketingData-taskId=" + groupPullMarketing.getId();
                        Object rateLimitKeyobject = redisTemplate.opsForValue().get(rateLimitKey);
                        if (rateLimitKeyobject == null) {
                            //保存限流key
                            redisTemplate.opsForValue().set(rateLimitKey, rateLimitKey, 300, TimeUnit.SECONDS);
                        } else {
                            continue;
                        }

                        try {

                            boolean verifyResult = verifyMarketingData(groupPullMarketing);
                            if(!verifyResult){
                                continue;
                            }

                            //修改营销数据状态为已处理
                            groupPullMarketing.setHanderTime(now);
                            groupPullMarketing.setHander(1);
                            groupPullMarketing.setUpdateTime(now);
                            groupPullMarketingMapper.updateByIdSelective(groupPullMarketing);

                            //查询该机器人的配置方案
                            WwDevice wwDevice = wwDeviceMapper.queryById(groupPullMarketing.getDeviceUniqueId());
                            Device device = DeviceTools.transDevice(wwDevice);
                            if (device == null) {
                                log.error("处理群邀请再次营销数据出错，未找到该机器人，deviceUniqueId={}", groupPullMarketing.getDeviceUniqueId());
                                continue;
                            }
                            WwCustomer wwCustomer = wwCustomerMapper.queryByDeviceUniqueIdAndWxid(device.getDeviceUniqueId(), groupPullMarketing.getWxid());
                            if (wwCustomer == null) {//未查询到该会员，直接跳出
                                continue;
                            }
                            List<GroupPullData> groupPullDataList = JSONObject.parseArray(groupPullMarketing.getGroupPullDatas(), GroupPullData.class);
                            //封装拉群数据
                            List<GroupPullMsgData> groupPullMsgDataList = groupPullDataService.handGroupPullData(merId, groupPullDataList, wwCustomer, device);
                            if (groupPullMsgDataList != null && groupPullMsgDataList.size() > 0) {
                                //发送拉群消息
                                msgSendService.groupPullMsgSend(device.getMerId(), device, wwCustomer, groupPullMsgDataList, groupPullMarketing.getType(), groupPullMarketing.getPlanId(), false, null, MicaMsgSource.PULL_GROUP_MARKETING.getCode(), false);
                            }
                        } catch (Exception e) {
                            log.error("--自动处理拉群营销数据失败", e.getMessage(), e);
                        } finally {
                            //保存成功之后，手动删除限流redisKey
                            redisTemplate.delete(rateLimitKey);
                        }
                    }

                    groupPullMarketingQuery.setIdStart(idStart);
                    groupPullMarketingList = groupPullMarketingMapper.findByList(page, groupPullMarketingQuery);
                }
            } catch (Exception e) {
                log.error(e.getMessage(), e);
            } finally {
                //删除限流key
                redisTemplate.delete(taskLimitKet);
            }
        }catch (Exception e){
            log.error(e.getMessage() ,  e);
        }finally {
            log.info("--监控系统日志--结束--");
        }

    }

    /**
     * 验证营销数据有效性
     * @author jitwxs
     * @date 2024/4/15 10:16
     * @param groupPullMarketing 
     * @return boolean
     */
    public boolean verifyMarketingData(GroupPullMarketing groupPullMarketing){

        boolean resulst = true;

        if(groupPullMarketing == null){
            return false;
        }

        //默认黑名单不通过
        WwCustomerBlacklist wwCustomerBlacklist = wwCustomerBlacklistMapper.selectByWxid(groupPullMarketing.getMerId(), groupPullMarketing.getWxid());
        if(wwCustomerBlacklist != null){ //在黑名单中
            return false;
        }

        //类型（1；关键词拉群；2-标签拉群；3-批量拉群；4-新客户运营拉群；5-智能应答触发问题拉群）
        Integer type = Tools.getInteger(groupPullMarketing.getType());
        if(type.intValue() == 1 || type.intValue() == 2){//关键词和标签拉群
            //查询该配置方案是否存在
            GroupPullConfigDevice groupPullConfigDevice = groupPullConfigDeviceMapper.selectByTaskIdAndDeviceUniqueId(groupPullMarketing.getPlanId(), groupPullMarketing.getDeviceUniqueId());
            if(groupPullConfigDevice == null){
                //修改营销数据状态为已处理
                groupPullMarketing.setHanderTime(DateUtil.getTime());
                groupPullMarketing.setHander(1);
                groupPullMarketing.setUpdateTime(DateUtil.getTime());
                groupPullMarketingMapper.updateByIdSelective(groupPullMarketing);
                return false;
            }

            //限制是否休眠
            OperatorPlanDeviceRule operatorPlanDeviceRule = JSONObject.parseObject(groupPullConfigDevice.getRule(), OperatorPlanDeviceRule.class);
            boolean sleepFlag = SleepTimeTools.verifySleepTime(operatorPlanDeviceRule);
            if(sleepFlag){
                return false;
            }
        }else if(type.intValue() == 3){//批量拉群
            //查询该配置方案是否存在
            GroupPullJobDevice groupPullJobDevice = groupPullJobDeviceMapper.selectByJobIdAndDeviceUniqueId(groupPullMarketing.getPlanId(), groupPullMarketing.getDeviceUniqueId());
            if(groupPullJobDevice == null){
                //修改营销数据状态为已处理
                groupPullMarketing.setHanderTime(DateUtil.getTime());
                groupPullMarketing.setHander(1);
                groupPullMarketing.setUpdateTime(DateUtil.getTime());
                groupPullMarketingMapper.updateByIdSelective(groupPullMarketing);
                return false;
            }

            //限制是否休眠
            OperatorPlanDeviceRule operatorPlanDeviceRule = JSONObject.parseObject(groupPullJobDevice.getRule(), OperatorPlanDeviceRule.class);
            boolean sleepFlag = SleepTimeTools.verifySleepTime(operatorPlanDeviceRule);
            if(sleepFlag){
                return false;
            }
        }else if(type.intValue() == 4){//新客户运营拉群
            //查询该配置方案是否存在
            OperatePlanDevice operatePlanDevice = operatePlanDeviceMapper.selectByPlanIdAndDeviceUniqueId(groupPullMarketing.getPlanId(), groupPullMarketing.getDeviceUniqueId());
            if(operatePlanDevice == null){
                //修改营销数据状态为已处理
                groupPullMarketing.setHanderTime(DateUtil.getTime());
                groupPullMarketing.setHander(1);
                groupPullMarketing.setUpdateTime(DateUtil.getTime());
                groupPullMarketingMapper.updateByIdSelective(groupPullMarketing);
                return false;
            }

            //限制是否休眠
            OperatorPlanDeviceRule operatorPlanDeviceRule = JSONObject.parseObject(operatePlanDevice.getRule(), OperatorPlanDeviceRule.class);
            boolean sleepFlag = SleepTimeTools.verifySleepTime(operatorPlanDeviceRule);
            if(sleepFlag){
                return false;
            }
        }else if(type.intValue() == 5){//智能应答拉群
            //查询该配置方案是否存在
            FaqReplyDevice faqReplyDevice = faqReplyDeviceMapper.selectByTaskIdAndDeviceUniqueId(groupPullMarketing.getPlanId(), groupPullMarketing.getDeviceUniqueId());
            if(faqReplyDevice == null){
                //修改营销数据状态为已处理
                groupPullMarketing.setHanderTime(DateUtil.getTime());
                groupPullMarketing.setHander(1);
                groupPullMarketing.setUpdateTime(DateUtil.getTime());
                groupPullMarketingMapper.updateByIdSelective(groupPullMarketing);
                return false;
            }

            //限制是否休眠
            OperatorPlanDeviceRule operatorPlanDeviceRule = JSONObject.parseObject(faqReplyDevice.getRule(), OperatorPlanDeviceRule.class);
            boolean sleepFlag = SleepTimeTools.verifySleepTime(operatorPlanDeviceRule);
            if(sleepFlag){
                return false;
            }
        }

        return true;

    }


}
